#pragma once

#include <iostream>
#include "main.h"
#include "ar8030_com.h"

typedef enum {
    AR_UPGRADE_NONE = 0,
    AR_UPGRADE_UART = 1,
    AR_UPGRADE_SDIO = 2,
    AR_UPGRADE_USB = 3,
    AR_UPGRADE_BB = 4
}AR_UPGRADE;

typedef enum {
    AR_UPGRADE_ACK = 1,
    AR_UPGRADE_READ = 2,
    AR_UPGRADE_WRITE = 3,
    AR_UPGRADE_EXIT = 4,
    AR_UPGRADE_REBOOT = 5,
    AR_UPGRADE_CRC32 = 6,
}AR_UPGRADE_CMD;

typedef enum {
    AR_UPGRADE_RESPONSE_OK = 0,
    AR_UPGRADE_RESPONSE_INVALID_MAGIC = 1,
    AR_UPGRADE_RESPONSE_INVALID_CMD = 2,
    AR_UPGRADE_RESPONSE_INVALID_LEN = 3,
    AR_UPGRADE_RESPONSE_INVALID_ADDR = 4,
    AR_UPGRADE_RESPONSE_OPERATE_FAIL = 5,
    AR_UPGRADE_RESPONSE_CRC32_FAIL = 6
}AR_UPGRADE_RESPONSE;

enum part_status {
    PART_STATUS_NOCHANGE = 0,
    PART_STATUS_CHANGE,
    PART_STATUS_UNKNOWN
};

class ar8030_usb_tool
{
public:
    ar8030_usb_tool();
    ~ar8030_usb_tool();

    int usb_tool_command_parse(int argc, char* argv[]);
    int usb_tool_command_help();

    void usb_delay_ms(unsigned int ms);

private:
    class ar_usb* usb;
    libusb_device_handle* handle;
    int last_status;
    unsigned int phy_reg_index;

    //romcode
    int write_reg32(unsigned int addr, unsigned int val);
    int usb_tool_upload_file_romcode(unsigned long long addr, std::string file_path);
    int usb_tool_romcode_2_upgrade(std::string file_path, std::string bb_cfg_path);


    //rtos
    int send_speed_test();
    int recv_speed_test();
    int echo_speed_test();
    int dump_upgrade_file(unsigned char* buf);
    int do_verify_image(unsigned char* img);
    int ar8030_hid_read(unsigned char* data, unsigned short len, unsigned int port);
    int ar8030_hid_write(void* header, unsigned int head_size, unsigned char* data, unsigned short len, unsigned int port);
    int ar8030_upgrade_wait_ack();
    int ar8030_upgrade_read(unsigned long long addr, unsigned short len, unsigned char* data);
    int ar8030_upgrade_write(unsigned long long addr, unsigned short len, unsigned char* data);
    int ar8030_upgrade_chk_crc(unsigned long long addr, unsigned int len, unsigned int target_crc);
    int ar8030_upgrade_partition(unsigned long long addr, unsigned int len, unsigned char* data);
    int ar8030_upgrade_partition_byname(struct upgrade_hdr* hdr, struct part_info* partitions,
        struct segment_info* segments, unsigned char* data, const char* partname);
    int ar8030_upgrade_dump_flash(unsigned long long addr, unsigned int len);
    int ar8030_upgrade(unsigned int index, std::string file_path);
    
    
    //int write_reg32_rtos(unsigned int index, unsigned long long addr, unsigned int val);
    //int read_reg32_rtos(unsigned int index, unsigned long long addr, unsigned int* val);
    //int usb_tool_get_upgrade_progress(unsigned char* data, unsigned int data_len);
    //int usb_tool_upgrade_uboot(unsigned int index, std::string file_path);
    //int usb_tool_upload_file_uboot(unsigned int index, unsigned long long addr, std::string file_path);
    //int usb_tool_download_file_uboot(unsigned int index, unsigned long long addr,
    //    unsigned int data_len, std::string file_path);
};